package org.concepts.java.antlr.calculator;

import static junit.framework.Assert.assertEquals;

import org.junit.Test;

public class TestCalculator {

  @Test
  public void testNoOperator() {
    assertEquals(2, Calculator.calculate("2"));
  }
  
  
  @Test
  public void testPlus() {
    assertEquals(3, Calculator.calculate("1 + 2"));
  }
  
  @Test
  public void testMinus() {
    assertEquals(3, Calculator.calculate("5 - 2"));
  }

  @Test
  public void testMultiply() {
    assertEquals(10, Calculator.calculate("5 * 2"));
  }

  @Test
  public void testDivide() {
    assertEquals(2, Calculator.calculate("10 / 5"));
  }

  @Test
  public void testOperatorPrecedence() {
   assertEquals(23, Calculator.calculate("3 + 4 * 5")); 
  }

  /**
   * Ensure that multiple and divide are processed left to right
   */
  @Test
  public void testLeftRightProcessingForSamePrecedence() {
   assertEquals(38, Calculator.calculate("3 + 10 * 7  / 2")); 
   assertEquals(33, Calculator.calculate("3 + 6  / 2 * 10")); 
  }
  
  @Test
  public void testUsingParenthesis() {
    assertEquals(23, Calculator.calculate("3 + 4 * 5")); 
    assertEquals(35, Calculator.calculate("(3 + 4) * 5")); 
    
  }

  /**
   * Ensures that nested parenthesis works fine and rounding is done properly.
   */
  @Test
  public void testAdvancedExression() {
    assertEquals(7, Calculator.calculate("((2 + 4) * 5) / 7 + (9 / 4 + 1)")); 
    
  }

  /**
   * Ensures that invalid character are ignored by the parser and it makes
   * best effort to calculate user input. Error message is sent to the error
   * stream.
   */
  @Test
  public void testIgnoterInvalidCharacterInvalidOperator() {
    assertEquals(9, Calculator.calculate("3 + a + 6"));
    assertEquals(8, Calculator.calculate("3 + b5"));
    assertEquals(3, Calculator.calculate("3 | b5"));
  }
  
  
}
